package com.wingsoft.task;


import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wingsoft.basic.domain.SoraConfig;
import com.wingsoft.basic.service.impl.SoraConfigServiceImpl;
import com.wingsoft.common.exception.ServiceException;
import com.wingsoft.common.utils.IdGenerator.IdGeneratorFactory;
import com.wingsoft.work.domain.UserTask;
import com.wingsoft.work.domain.UserTaskLog;
import com.wingsoft.work.domain.UserVip;
import com.wingsoft.work.service.impl.UserTaskLogServiceImpl;
import com.wingsoft.work.service.impl.UserTaskServiceImpl;
import com.wingsoft.work.service.impl.UserVipServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Component("userTaskJob")
public class UserTaskJob {
    @Autowired
    private UserTaskServiceImpl userTaskService;
    @Autowired
    private UserTaskLogServiceImpl userTaskLogService;
    @Autowired
    private IdGeneratorFactory idGeneratorFactory;
    @Autowired
    private UserVipServiceImpl userVipService;
    @Autowired
    private SoraConfigServiceImpl soraConfigService;

    public void doTask(){
        LambdaQueryWrapper<UserTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserTask::getStatus, 0);
        List<UserTask> list = userTaskService.list(wrapper);
        for(UserTask userTask : list){
            try {
                SoraConfig soraConfig = soraConfigService.getNextSoraConfig(userTask.getHisInterfaceType());
                if (!ObjectUtils.isEmpty(soraConfig)){
                    if (soraConfig.getType().equals("api.bltcy.ai")){
                        userTaskService.doTaskV1(userTask,soraConfig);
                    }else if(soraConfig.getType().equals("api-2.codeai.my")){
                        userTaskService.doTaskV2(userTask,soraConfig);
                    }else if(soraConfig.getType().equals("yunwu.ai")){
                        userTaskService.doTaskV3(userTask,soraConfig);
                    }
                }else {
                    //为空。说明都轮转过了。退回积分。
                    userTaskService.taskFinalFail(userTask);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void initTaskStatus(){
        LambdaQueryWrapper<UserTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserTask::getStatus, 1);
        List<UserTask> list = userTaskService.list(wrapper);
        for(UserTask userTask : list){
            try {
                SoraConfig soraConfig = soraConfigService.getByType(userTask.getNowInterfaceType());
                if (!ObjectUtils.isEmpty(soraConfig)){
                    if (soraConfig.getType().equals("api.bltcy.ai")){
                        userTaskService.getTaskV1(userTask,soraConfig);
                    }else if(soraConfig.getType().equals("api-2.codeai.my")){
                        userTaskService.getTaskV2(userTask,soraConfig);
                    }else if( soraConfig.getType().equals("yunwu.ai")){
                        userTaskService.getTaskV3(userTask,soraConfig);
                    }
                }else {
                    //接口已经删除，直接进入下一个流程
                    userTask.setStatus(0);
                    userTaskService.updateById(userTask);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void ossTask(){
        LambdaQueryWrapper<UserTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserTask::getOssStatus, 1);
        List<UserTask> list = userTaskService.list(wrapper);
        for(UserTask userTask : list){
            try {
                Map<String,Object> params = new HashMap<>();
                params.put("videoUrl",userTask.getVideoUrl());
                params.put("taskId",userTask.getTaskId());
                String time = System.currentTimeMillis()+"";
                params.put("timestamp",time);
                String key = "basic@abc@123456";
                String md5Pre = time+key;
                String checkedStr = DigestUtil.md5Hex(md5Pre);
                params.put("checkedStr", checkedStr);
                String result = HttpUtil.createPost("http://47.242.202.240:8080/process_video")
                        .header("Content-Type", "application/json")
                        .body(JSONUtil.toJsonStr(params))
                        .timeout(30000)
                        .execute()
                        .body();
                JSONObject jsonObject = JSONUtil.parseObj(result);
                String status = jsonObject.getStr("status");
                if (!ObjectUtils.isEmpty(status) && status.equals("success")){
                    String ossUrl = jsonObject.getStr("ossUrl");
                    userTask.setOssStatus(2);
                    userTask.setOssTime(userTask.getOssTime()+1);
                    userTask.setOssVideoUrl(ossUrl);
                    userTaskService.updateById(userTask);
                }else {
                    throw new ServiceException("请求失败！");
                }
            }catch (Exception e){
                if (userTask.getOssTime() == 2){
                    userTask.setOssStatus(3);
                }else {
                    userTask.setOssTime(userTask.getOssTime()+1);
                }
                userTaskService.updateById(userTask);
            }
        }
    }


    public void overTimeTask(){
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LambdaUpdateWrapper<UserVip> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(UserVip::getStatus, 2)
                .lt(UserVip::getExpireTime, todayStart); // 过期时间早于当前时间
        userVipService.update(updateWrapper);
    }
}
